﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_Burn2 : AreaSpell
    {
        public Spell_Burn2() { }

        private int DamageLow = 10;
        private int DamageHigh = 15;

        private int TotalDamage = 0;
        private int TickDamage = 0;

        private void MainCast(CreatureBase myCreatureBase, int MapX, int MapY, List<MapItem> MapItemsWithin12)
        {
            //Set Duration & Damage Per Character Stats
            DurationLow = 5;
            DurationHigh = 9;

            CastMapX = MapX;
            CastMapY = MapY;

            List<Character> CharactersWithinUpdateRange = new List<Character>();
            foreach (MapItem mapitem in MapItemsWithin12)
            {
                //Add this spell to each mapitem in range & record mapitem for timer
                if ((Math.Abs(mapitem.MapX - CastMapX) <= 1 && Math.Abs(mapitem.MapY - CastMapY) <= 1) &&
                    mapitem.Motion > 0 && mapitem.TerrainType != "Water" && mapitem.Transparent == true)
                {
                    if (spellIcon.Skill == "Fire")
                    {
                        foreach (Spell spell in mapitem.SpellLayer0)
                        {
                            if (spell.spellIcon.Name == "Burn" || spell.spellIcon.Name == "Burn 2" || spell.spellIcon.Name == "Burn 3")
                            {
                                mapitem.SpellLayer0.Remove(spell);
                                break;
                            }
                        }
                        mapitem.SpellLayer0.Add(this);
                    }
                    else if (spellIcon.Skill == "Ice")
                    {
                        foreach (Spell spell in mapitem.SpellLayer1)
                        {
                            if (spell.spellIcon.Name == "Hail Storm" || spell.spellIcon.Name == "Hail Storm 2" || spell.spellIcon.Name == "Hail Storm 3")
                            {
                                mapitem.SpellLayer1.Remove(spell);
                                break;
                            }
                        }
                        mapitem.SpellLayer1.Add(this);
                    }

                    MapItems.Add(mapitem);
                }
            }
            foreach (MapItem mapitem in MapItems)
            {
                foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                {
                    if (creatureBase.HP < 1)
                        continue;

                    int reducedDamage = creatureBase.CalculateGetSpellDamagePerResists(TotalDamage, this.spellIcon.Skill);
                    double resistRatio = reducedDamage / TotalDamage;
                    int actualDamage = System.Convert.ToInt32(TickDamage * resistRatio);
                    int absorbedDamage;
                    creatureBase.InflictSpellDamage(actualDamage, CastingCharacterID, CastingCreatureGUID, spellIcon.Skill, out absorbedDamage);
                }
            }
            foreach (MapItem mapitem in MapItems)
            {
                for (int x = 0; x < mapitem.CreaturesBases.Count; x++)
                {
                    CreatureBase creaturebase = (CreatureBase)mapitem.CreaturesBases[x];

                    if (creaturebase.HP < 1)
                    {
                        if (!(creaturebase is Character))
                        {
                            mapitem.CreaturesBases.RemoveAt(x);
                            x--;
                        }
                    }
                }
            }
            foreach (Character character in CharactersWithinUpdateRange)
            {
                character.AddMapItems(MapItems, false);

                if (spellIcon.Skill == "Fire")
                    character.PlaySound("FireBall", CastMapX, CastMapY);
            }

            //Start Spell Timer
            spellTimer.Start();
        }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, List<string> MoveList)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, MoveList, out MapItemsWithin12) == false)
                return;

            TotalDamage = Managers.GameHandler.random.Next(DamageLow, DamageHigh + 1);
            TotalDamage = SkillManager.AdjustForCombat(CastLevel, TotalDamage, myCreatureBase.IntelligenceTotal);
            TickDamage = TotalDamage;
            TotalDamage = TotalDamage * DurationHigh;

            MainCast(myCreatureBase, CastMapX, CastMapY, MapItemsWithin12);
        }

        protected override void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            TimerCounter = TimerCounter + 1;

            //Get MapLock
            LockItem MapLock = Managers.GameHandler.GetLockItem(MapID, Instance);

            //Lock MapLock
            lock (MapLock.LockObj)
            {
                Map CurrentMap = Managers.GameHandler.GetMap(MapID, Instance);

                //Stop Running if no mapitems
                bool FoundItem = false;
                foreach (MapItem mapitem in MapItems)
                {
                    if (mapitem.SpellLayer0.Contains(this) || mapitem.SpellLayer1.Contains(this))
                    {
                        FoundItem = true;
                        break;
                    }
                }
                if (FoundItem == false)
                    return;

                List<MapItem> MapItemsToUpdate = new List<MapItem>();

                foreach (MapItem mapitem in MapItems)
                {
                    bool foundSpell = false;
                    foreach (Spell spell in mapitem.SpellLayer0)
                    {
                        if (spell.SpellID == this.SpellID)
                        {
                            foundSpell = true;
                            break;
                        }
                    }
                    if (foundSpell == false)
                        continue;

                    if (TimerCounter >= DurationLow)
                    {
                        if (mapitem.MapX != CastMapX || mapitem.MapY != CastMapY)
                        {
                            int RemoveSpell = Managers.GameHandler.random.Next(-1, DurationHigh - TimerCounter);
                            if (RemoveSpell == -1)
                            {
                                if (spellIcon.Skill == "Fire")
                                    mapitem.SpellLayer0.Remove(this);
                                else if (spellIcon.Skill == "Ice")
                                    mapitem.SpellLayer1.Remove(this);

                                MapItemsToUpdate.Add(mapitem);
                                continue;
                            }
                        }
                        else if (TimerCounter >= DurationHigh)
                        {
                            if (spellIcon.Skill == "Fire")
                                mapitem.SpellLayer0.Remove(this);
                            else if (spellIcon.Skill == "Ice")
                                mapitem.SpellLayer1.Remove(this);

                            MapItemsToUpdate.Add(mapitem);
                            continue;
                        }
                    }
                    if (spellIcon.Skill == "Fire")
                    {
                        Corpse corpse = CurrentMap.LootMngr.GetFirstCorpse(mapitem.MapX, mapitem.MapY);
                        if (corpse != null)
                        {
                            Managers.GameHandler.Corpse_Roll(null, MapID, Instance, mapitem.MapX, mapitem.MapY, corpse.GameUID);
                        }
                        else
                        {
                            CorpseCharacter charCorpse = CurrentMap.LootMngr.GetFirstCharacterCorpse(mapitem.MapX, mapitem.MapY);
                            if (charCorpse != null)
                            {
                                Managers.GameHandler.Corpse_Roll(null, MapID, Instance, mapitem.MapX, mapitem.MapY, charCorpse.GameUID);
                                Managers.GameHandler.Resurrect(charCorpse.MyCharacter);
                            }
                        }
                    }
                    MapItemsToUpdate.Add(mapitem);
                }

                List<Character> CharsToUpdate = new List<Character>();
                //Send Updated Hexes to all characters within 8 of any hex effected
                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    foreach (MapItem mitem in MapItems)
                    {
                        if (mapitem.MapX - mitem.MapX >= -12 && mapitem.MapX - mitem.MapX <= 12 && mapitem.MapY - mitem.MapY >= -12 && mapitem.MapY - mitem.MapY <= 12)
                        {
                            foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                            {
                                if (creatureBase is Character)
                                    CharsToUpdate.Add((Character)creatureBase);
                            }
                            break;
                        }
                    }
                }

                foreach (MapItem mapitem in MapItemsToUpdate)
                {
                    foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                    {
                        if (creatureBase.HP < 1)
                            continue;

                        int reducedDamage = creatureBase.CalculateGetSpellDamagePerResists(TotalDamage, this.spellIcon.Skill);
                        double resistRatio = reducedDamage / TotalDamage;
                        int actualDamage = System.Convert.ToInt32(TickDamage * resistRatio);
                        int absorbedDamage;
                        creatureBase.InflictSpellDamage(actualDamage, CastingCharacterID, CastingCreatureGUID, spellIcon.Skill, out absorbedDamage);

                    }
                    //Remove Creatures
                    bool Complete = false;
                    while (Complete == false)
                    {
                        int count = 0;
                        if (mapitem.CreaturesBases.Count == 0)
                            Complete = true;
                        foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                        {
                            count = count + 1;
                            if (creatureBase.HP < 1 && !(creatureBase is Character))
                            {
                                mapitem.CreaturesBases.Remove(creatureBase);
                                break;
                            }
                            if (count == mapitem.CreaturesBases.Count)
                            {
                                Complete = true;
                            }
                        }
                    }
                }
                foreach (Character character in CharsToUpdate)
                {
                    character.AddMapItems(MapItemsToUpdate, false);
                }
            
            }//End Lock

            spellTimer.Start();
        }
    }
}
